package de.haw.avl;

public class Node implements Comparable<Node> {

	private Node leftHand;
	private Node rightHand;

	private Integer value;
	private Integer height;

	public Node(int value) {
		this(null, null, value, 0);
	}

	public Node(Node left, Node right, int value) {
		this(left, right, value, 0);
	}

	public Node(Node left, Node right, int value, int hight) {
		super();
		this.leftHand = left;
		this.rightHand = right;
		this.value = value;
		this.height = 0;
	}

	public void resetHeight() {
		int leftHeight = -1;
		int rightHeight = -1;

		if (getLeftHand() != null) {
			leftHeight = getLeftHand().getHeight();
		}
		if (getRightHand() != null) {
			rightHeight = getRightHand().getHeight();
		}
		this.height = 1 + Math.max(leftHeight, rightHeight);
	}

	public Node getLeftHand() {
		return leftHand;
	}

	public void setLeftHand(Node leftHand) {
		this.leftHand = leftHand;
	}

	public Node getRightHand() {
		return rightHand;
	}

	public void setRightHand(Node rightHand) {
		this.rightHand = rightHand;
	}

	public Integer getValue() {
		return value;
	}

	public void setValue(Integer value) {
		this.value = value;
	}

	public Integer getHeight() {
		return height;
	}

	@Override
	public int compareTo(Node o) {
		return value.compareTo(o.getValue());
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((value == null) ? 0 : value.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Node other = (Node) obj;
		if (value == null) {
			if (other.value != null)
				return false;
		} else if (!value.equals(other.value))
			return false;
		return true;
	}

	@Override
	public String toString() {
		return value.toString();
	}

	public int summPreorder() {
		int summe = getValue();
		if (getLeftHand() != null) {
			summe += getLeftHand().summPreorder();
		}
		if (getRightHand() != null) {
			summe += getRightHand().summPreorder();
		}
		return summe;
	}

	public int summPostorder() {
		int summe = 0;
		if (getLeftHand() != null) {
			summe += getLeftHand().summPreorder();
		}
		if (getRightHand() != null) {
			summe += getRightHand().summPreorder();
		}
		summe += getValue();
		return summe;
	}

	public int summInorder() {
		int summe = 0;
		if (getLeftHand() != null) {
			summe += getLeftHand().summPreorder();
		}
		summe += getValue();
		if (getRightHand() != null) {
			summe += getRightHand().summPreorder();
		}
		return summe;
	}

	@Override
	/**
	 * Erzeugen einer echten rekursiven Kopie
	 */
	protected Node clone() {
		return new Node(getLeftHand() != null ? getLeftHand().clone() : null, getRightHand() != null ? getRightHand().clone() : null, this.value, this.height);
	}

	public Node find(Node node) {
		Node result = null;
		if (this.equals(node)) {
			return this;
		}
		if (getLeftHand().getValue() < node.getValue()) {
			result = getLeftHand().find(node);
		}else{
			result = getRightHand().find(node);
		}

		return result;
	}

	
}
